/**
 * 
 */
package hawk.example.juni5.testkit;

import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.testkit.engine.EventConditions.abortedWithReason;
import static org.junit.platform.testkit.engine.EventConditions.container;
import static org.junit.platform.testkit.engine.EventConditions.engine;
import static org.junit.platform.testkit.engine.EventConditions.event;
import static org.junit.platform.testkit.engine.EventConditions.finishedSuccessfully;
import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure;
import static org.junit.platform.testkit.engine.EventConditions.skippedWithReason;
import static org.junit.platform.testkit.engine.EventConditions.started;
import static org.junit.platform.testkit.engine.EventConditions.test;
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.instanceOf;
import static org.junit.platform.testkit.engine.TestExecutionResultConditions.message;

import java.io.StringWriter;
import java.io.Writer;

import org.junit.jupiter.api.Test;
import org.junit.platform.testkit.engine.EngineTestKit;
import org.opentest4j.TestAbortedException;

public class EngineTestKitAllEventsDemo {
	@Test
	void verifyAllJupiterEvents() {
		Writer writer = new StringWriter();// create a java.io.Writer for debug output

		EngineTestKit //
				.engine("junit-jupiter") // Select the JUnit Jupiter TestEngine.
				.selectors(selectClass(ExampleTestCase.class)) // Select the ExampleTestCase test class.
				.execute() // Execute the TestPlan.
				.allEvents() // Filter by all events.
				.debug(writer) // Print all events to the supplied writer for debugging purposes.
								// Debug information can also be written to an OutputStream such as System.out or System.err.
				.assertEventsMatchExactly(//
						event(engine(), started()), //
						event(container(ExampleTestCase.class), started()), //
						event(test("skippedTest"), skippedWithReason("for demonstration purposes")), //
						event(test("succeedingTest"), started()), //
						event(test("succeedingTest"), finishedSuccessfully()), //
						event(test("abortedTest"), started()), //
						event(test("abortedTest"),
								abortedWithReason(instanceOf(TestAbortedException.class), message(m -> m.contains("abc does not contain Z")))), //
						event(test("failingTest"), started()), //
						event(test("failingTest"), finishedWithFailure(instanceOf(ArithmeticException.class), message("/ by zero"))), //
						event(container(ExampleTestCase.class), finishedSuccessfully()), //
						event(test("abortedTest"),
								abortedWithReason(instanceOf(TestAbortedException.class), message(m -> m.contains("abc does not contain Z")))), //
						event(test("failingTest"), started()), //
						event(test("failingTest"), finishedWithFailure(instanceOf(ArithmeticException.class), message("/ by zero"))), //
						event(container(ExampleTestCase.class), finishedSuccessfully()), event(engine(), finishedSuccessfully()) //

				);
	}
}
